package com.lh0811.forge.pserv.uacs.server.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.lh0811.forge.dependency.basic_code.BeanHelper;
import com.lh0811.forge.dependency.basic_code.IdWorker;
import com.lh0811.forge.dependency.basic_code.ListToTreeUtil;
import com.lh0811.forge.dependency.basic_web.exception.CommonException;
import com.lh0811.forge.dependency.basic_web.response.ServerResponse;
import com.lh0811.forge.dependency.security.client.component.SecurityUtil;
import com.lh0811.forge.dependency.security.core.model.entity.SecurityAuthority;
import com.lh0811.forge.pserv.uacs.api.component.data_scope.DataScope;
import com.lh0811.forge.pserv.uacs.api.param.*;
import com.lh0811.forge.pserv.uacs.api.vo.TDesignCascaderVo;
import com.lh0811.forge.pserv.uacs.api.vo.UacsPlateResQueryVo;
import com.lh0811.forge.pserv.uacs.api.vo.UacsPlateResTreeVo;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateResDao;
import com.lh0811.forge.pserv.uacs.server.repository.dao.UacsPlateRoleResRefDao;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateRes;
import com.lh0811.forge.pserv.uacs.server.repository.entity.UacsPlateRoleResRef;
import com.lh0811.forge.pserv.uacs.server.service.PlateResService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PlateResServiceImpl implements PlateResService {

    @Resource
    private UacsPlateResDao uacsPlateResDao;

    @Resource
    private UacsPlateRoleResRefDao uacsPlateRoleResRefDao;

    // 创建资源
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void plateResCreate(UacsPlateResCreateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();

        UacsPlateRes uacsPlateRes = new UacsPlateRes();
        uacsPlateRes.setId(IdWorker.nextId()); // 主键
        uacsPlateRes.setPid(param.getPid()); // 父节点id
        uacsPlateRes.setResName(param.getResName()); // 资源名称
        uacsPlateRes.setResType(param.getResType()); // 资源类型： 00-菜单 01-操作按钮(接口) 02-权限码
        uacsPlateRes.setUrl(param.getUrl()); // 请求地址
        uacsPlateRes.setCode(param.getCode()); // 权限码
        uacsPlateRes.setIcon(param.getIcon()); // 图标
        uacsPlateRes.setOrderNo(param.getOrderNo()); // 排序
        uacsPlateRes.setMeta(param.getMeta()); // 元数据
        uacsPlateRes.setNotes(param.getNotes()); // 备注
        uacsPlateRes.setLeafFlag(Boolean.TRUE); // 是否是叶子节点
        uacsPlateRes.setRouter("0," + uacsPlateRes.getId());
        uacsPlateRes.setCreateTime(new Date()); // 创建时间
        uacsPlateRes.setCreateBy(Long.valueOf(securityAuthority.getUserId())); // 创建人
        UacsPlateRes parentRes = uacsPlateResDao.getById(param.getPid());
        if (ObjectUtils.isNotEmpty(parentRes)) {
            uacsPlateRes.setRouter(parentRes.getRouter() + "," + uacsPlateRes.getId()); // 路由
        }
        uacsPlateResDao.save(uacsPlateRes);
    }

    // 删除资源
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void plateResDelete(Long resId) throws Exception {
        UacsPlateRes uacsPlateRes = uacsPlateResDao.getById(resId);
        if (ObjectUtils.isEmpty(uacsPlateRes)) {
            throw CommonException.create(ServerResponse.createByError("资源信息不存在"));
        }
        // 移除角色资源关系
        List<UacsPlateRoleResRef> roleResRefList = uacsPlateRoleResRefDao.lambdaQuery().eq(UacsPlateRoleResRef::getResId, resId).list();
        if (CollectionUtils.isNotEmpty(roleResRefList)) {
            uacsPlateRoleResRefDao.removeByIds(roleResRefList.stream().map(ele -> ele.getId()).collect(Collectors.toList()));
        }
        // 移除资源信息
        uacsPlateResDao.removeById(resId);

        // 判断父节点
        UacsPlateRes parentRes = uacsPlateResDao.getById(uacsPlateRes.getPid());
        if (ObjectUtils.isNotEmpty(parentRes)) {
            if (uacsPlateResDao.lambdaQuery().eq(UacsPlateRes::getPid, parentRes.getId()).count() == 0) {
                uacsPlateResDao.lambdaUpdate()
                        .set(UacsPlateRes::getLeafFlag, Boolean.TRUE)
                        .eq(UacsPlateRes::getId, parentRes.getId())
                        .update();
            }
        }
    }

    // 资源更新
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void plateResUpdate(UacsPlateResUpdateParam param) throws Exception {
        SecurityAuthority securityAuthority = SecurityUtil.getSecurityAuthority();
        UacsPlateRes updateInfo = BeanHelper.copyBean(param, UacsPlateRes.class);
        // 判断是否更新父节点
        UacsPlateRes parentRes = uacsPlateResDao.getById(param.getPid());
        if (ObjectUtils.isNotEmpty(parentRes)) {
            updateInfo.setRouter(parentRes.getRouter() + "," + updateInfo.getId()); // 路由
            if (uacsPlateResDao.lambdaQuery().eq(UacsPlateRes::getPid, parentRes.getId()).count() > 0) {
                uacsPlateResDao.lambdaUpdate()
                        .set(UacsPlateRes::getLeafFlag, Boolean.FALSE)
                        .eq(UacsPlateRes::getId, parentRes.getId())
                        .update();
            }
        }
        // 更新数据
        uacsPlateResDao.updateById(updateInfo);
    }

    // 资源查询(分页)
    @Override
    @DataScope
    public PageInfo<UacsPlateResQueryVo> plateResQueryPage(UacsPlateResQueryPageParam param) throws Exception {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<UacsPlateRes> list = uacsPlateResDao.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(param.getPid()), UacsPlateRes::getPid, param.getPid())
                .like(ObjectUtils.isNotEmpty(param.getResName()), UacsPlateRes::getResName, param.getResName())
                .eq(ObjectUtils.isNotEmpty(param.getResType()), UacsPlateRes::getResType, param.getResType())
                .eq(ObjectUtils.isNotEmpty(param.getResType()), UacsPlateRes::getResType, param.getResType())
                .orderByDesc(UacsPlateRes::getCreateTime)
                .list();
        PageInfo pageInfo = new PageInfo<>(list);
        PageHelper.clearPage();
        pageInfo.setList(BeanHelper.copyList(list, UacsPlateResQueryVo.class));
        return pageInfo;
    }

    // 资源查询(不分页)
    @Override
    @DataScope
    public List<UacsPlateResQueryVo> plateResQueryList(UacsPlateResQueryListParam param) throws Exception {
        List<UacsPlateRes> list = uacsPlateResDao.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(param.getPid()), UacsPlateRes::getPid, param.getPid())
                .like(ObjectUtils.isNotEmpty(param.getResName()), UacsPlateRes::getResName, param.getResName())
                .eq(ObjectUtils.isNotEmpty(param.getResType()), UacsPlateRes::getResType, param.getResType())
                .eq(ObjectUtils.isNotEmpty(param.getResType()), UacsPlateRes::getResType, param.getResType())
                .orderByDesc(UacsPlateRes::getCreateTime)
                .list();
        return BeanHelper.copyList(list, UacsPlateResQueryVo.class);
    }

    // 资源查询(树结构)
    @Override
    @DataScope
    public List<UacsPlateResTreeVo> plateResQueryTree(UacsPlateResQueryTreeParam param) throws Exception {
        List<UacsPlateRes> list = uacsPlateResDao.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(param.getPid()), UacsPlateRes::getPid, param.getPid())
                .like(ObjectUtils.isNotEmpty(param.getResName()), UacsPlateRes::getResName, param.getResName())
                .eq(ObjectUtils.isNotEmpty(param.getResType()), UacsPlateRes::getResType, param.getResType())
                .eq(ObjectUtils.isNotEmpty(param.getResType()), UacsPlateRes::getResType, param.getResType())
                .orderByAsc(UacsPlateRes::getOrderNo)
                .list();
        JSONArray jsonArray = ListToTreeUtil.listToTree(list, "0", "pid", "id", "children");
        return jsonArray.toJavaList(UacsPlateResTreeVo.class);
    }


    // 资源查询(级联结构)
    @Override
    @DataScope
    public List<TDesignCascaderVo> plateResQueryTreeCascader() throws Exception {
        List<UacsPlateRes> list = uacsPlateResDao.lambdaQuery()
//                .eq(UacsPlateRes::getResType, UacsContant.ResType.菜单.getCode())
                .orderByAsc(UacsPlateRes::getOrderNo)
                .list();
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        List<TDesignCascaderVo> cascaderVoList = list.stream().map(ele -> {
            TDesignCascaderVo cascaderVo = new TDesignCascaderVo();
            cascaderVo.setPvalue(ele.getPid());
            cascaderVo.setValue(ele.getId());
            cascaderVo.setLabel(ele.getResName());
            return cascaderVo;
        }).collect(Collectors.toList());
        JSONArray jsonArray = ListToTreeUtil.listToTree(cascaderVoList, "0", "pvalue", "value", "children");
        return jsonArray.toJavaList(TDesignCascaderVo.class);
    }


}
